package com.sinsz.common;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sinsz.common.exception.ApiException;
import com.sinsz.common.exception.DefaultError;
import com.sinsz.common.exception.IError;
import org.nutz.json.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

/**
 * 信息返回对象
 * @author chenjianbo
 */
public class Result<T> implements Serializable {

    private static final long serialVersionUID = -2020301718893317864L;

    private static final Logger logger = LoggerFactory.getLogger(Result.class);

    /**
     * 错误代码
     * 默认0表示成功
     */
    private int errCode;

    /**
     * 错误消息
     */
    private String errMsg;

    /**
     * 返回数据
     */
    private T body;

    /**
     * 异常信息栈
     */
    private Throwable cause;

    public int getErrCode() {
        return errCode;
    }

    public void setErrCode(int errCode) {
        this.errCode = errCode;
    }

    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    public T getBody() {
        return body;
    }

    public void setBody(T body) {
        this.body = body;
    }

    public Throwable getCause() {
        return cause;
    }

    public void setCause(Throwable cause) {
        this.cause = cause;
    }

    /**
     * 限制外部创建
     * 构造方法
     */
    private Result() {
    }

    public Result(int errCode, String errMsg) {
        this.errCode = errCode;
        this.errMsg = errMsg;
    }

    /**
     * 成功返回
     * <p>
     *     不带返回数据
     * </p>
     * @return
     */
    public synchronized static <T> Result<T> ok(){
        return ok(null);
    }

    /**
     * 成功返回
     * <p>
     *     带返回数据
     * </p>
     * @param body  数据
     * @param <T>   返回类型
     * @return
     */
    public synchronized static <T> Result<T> ok(T body) {
        Result<T> result = new Result<>(0, "");
        if (body != null) {
            result.setBody(body);
        }
        return result;
    }

    /**
     * 访问失败
     * @param error 失败错误代码
     * @param stack 失败栈
     * @return
     */
    public synchronized static Result fail(IError error, Throwable stack) {
        error = error == null ? DefaultError.SYSTEM_ERR_01 : error;
        Result result = new Result(error.errCode(), error.errMsg());
        result.setCause(stack);
        return result;
    }

    /**
     * 未找到请求请返回
     * @return
     */
    public synchronized static Result notFound() {
        return Json.fromJson(Result.class, new ApiException(DefaultError.NOT_FOUND_01).toString());
    }

    /**
     * 系统异常请求返回
     * @return
     */
    public synchronized static Result systemError() {
        return Json.fromJson(Result.class, new ApiException(DefaultError.SYSTEM_ERR_01).toString());
    }

    /**
     * 请求标识不能为空请求返回
     * @return
     */
    public synchronized static Result requestTagError() {
        return Json.fromJson(Result.class, new ApiException(DefaultError.REQUEST_TAG_01).toString());
    }

    @Override
    public String toString() {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            logger.error(">>>>> Format json exception!");
        }
        return super.toString();
    }

}
